/* drivers/leds/leds-s3c24xx.c
 *
 * (c) 2006 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * s5pv210 - LEDs GPIO driver
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/slab.h>   // kzalloc 函数库

#include <linux/platform_device.h> // platform_driver
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/mod_devicetable.h>   // platform_device_id  头文件

///sys/bus/platform/drivers/my_platform_device  会创建文件

/**
 * 目的： 平台总线driver和 devices匹配 模版
 * 
 * 
 * 
 *  1. 定义platform_driver
    2. 
 *  // 注册平台驱动
    ret = platform_driver_register(&my_platform_driver);
     3. 匹配上调用 my_platform_probe
 *
 */ 


     struct resource *res_mem, *res_irq;
// 平台设备的探测函数
// 不管首先加载device还是driver ，都可以进入 my_platform_probe函数 
static int my_platform_probe(struct platform_device *pdev)
{
    printk(KERN_INFO "my_platform_probe: Probing platform device\n");
 

 
    // 方法1：直接访问 platform_device 结构体的资源数组
    if (pdev->num_resources >= 2) {
        struct resource *res_mem = &pdev->resource[0];
        struct resource *res_irq = &pdev->resource[1];
 
        // 使用获取到的硬件资源进行处理
        printk("Method 1: Memory Resource: start = 0x%llx, end = 0x%llx\n",
                res_mem->start, res_mem->end);
        printk("Method 1: IRQ Resource: number = %lld\n", res_irq->start);
    }
 
    // 方法2：使用 platform_get_resource() 获取硬件资源
    // 参数1：  platform_device
    // 参数2：   my_resources的 flags
    // 参数3:   同类资源的索引号，比如有2个 IORESOURCE_IRQ ，那么第二个就是1 ，这个只有一个IORESOURCE_IRQ 和一个 IORESOURCE_MEM
    res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!res_mem) {
        dev_err(&pdev->dev, "Failed to get memory resource\n");
        return -ENODEV;
    }
 
    res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
    if (!res_irq) {
        dev_err(&pdev->dev, "Failed to get IRQ resource\n");
        return -ENODEV;
    }
 

 //  Memory Resource: start = 0xfe760000, end = 0xfe760003
    // 使用获取到的硬件资源进行处理
    printk("Method 2: Memory Resource: start = 0x%llx, end = 0x%llx\n",
            res_mem->start, res_mem->end);
    printk("Method 2: IRQ Resource: number = %lld\n", res_irq->start);


// 把之前的代码拷贝过来！！！ 
 
    return 0;
}
 
// 平台设备的移除函数
static int my_platform_remove(struct platform_device *pdev)
{
    printk(KERN_INFO "my_platform_remove: Removing platform device\n");
 
    // 清理设备特定的操作
    // ...
 
    return 0;
}

/**
 *  如果定义了id_table , 匹配id_table的name  如果有id_table ， id_table匹配不上，返回fasle 
 *    
 *  如果没有定义id_table: 
 *  匹配 platform_driver的name 


 * id_table 功能， 一个驱动匹配 多个设备
 */
const struct platform_device_id mydriveer_id_table ={
         .name="my_platform_device",
};


// 定义平台驱动结构体
static struct platform_driver my_platform_driver = {
    .probe = my_platform_probe,
    .remove = my_platform_remove,
    .driver = {
        .name = "my_platform_device",
        .owner = THIS_MODULE,
    },
    .id_table = &mydriveer_id_table,   
};
// my_platform_device

static int __init my_platform_driver_init(void)
{
    int ret;
    // 注册平台驱动
    ret = platform_driver_register(&my_platform_driver);
    if (ret) {
        printk(KERN_ERR "Failed to register platform driver\n");
        return ret;
    }
    printk(KERN_INFO "my_platform_driver: Platform driver initialized\n");
    return 0;
                      
}

static void __exit my_platform_driver_exit(void)
{
    printk(KERN_INFO "This is platform_driver_unregister exit   \n");
  	platform_driver_unregister(&my_platform_driver);
}



module_init(my_platform_driver_init);
module_exit(my_platform_driver_exit);

MODULE_AUTHOR("tony <tony.deng321@gmail.com>");
MODULE_DESCRIPTION("X210 LED driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("s5pv210-led");
